import {defineStore} from "pinia";
import {WebSocketClient} from '@/utils/websocket';

// 定义 store 的类型
interface WebSocketStoreState {
    ws: WebSocketClient | null;
    listeners: Map<string, (data: any) => void>;
}

interface IMessage {
    id: string | undefined
    type: string
    data: any
    sender: string
}

export const useWebSocketStore = defineStore('websocketStore', {
    state: (): WebSocketStoreState => ({
        ws: null,
        listeners: new Map(), // 存储所有页面注册的回调函数
    }),
    actions: {
        /**
         * 连接 WebSocket
         */
        connect() {
            if (this.ws) return;

            this.ws = new WebSocketClient({
                url: 'ws://127.0.0.1:9328/ws',
                autoReconnect: false,
                onMessage: (data: IMessage) => {
                    if  (['MESSAGE'].includes(data.type)) {
                        this.listeners.get(data.type)?.(data);
                    } else {
                        this.listeners.get(data.id || data.type)?.(data);
                    }
                }
            });
            this.ws.doConnect();
        },

        /**
         * 关闭连接
         */
        disconnect(): void {
            if (this.ws) {
                this.ws.close(1000, '关闭连接, Bye...');
                this.ws = null;
            }
        },

        /**
         * 页面注册消息监听
         * @param key 消息类型
         * @param callback 回调函数
         */
        registerListener(key: string, callback: (data: any) => void): void {
            if (this.listeners.has(key)) {
                console.warn(`Listener with id '${key}' is already registered.`);
            }
            this.listeners.set(key, callback);
        },

        /**
         * 页面注销监听
         * @param key 消息类型
         */
        removeListener(key: string): void {
            if (!this.listeners.delete(key)) {
                console.warn(`Listener with id '${key}' not found.`);
            }
        },

        /**
         * 发送消息
         * @param data 消息数据
         * @param type 消息类型
         */
        send<T = any>(data: T, type = 'message'): void {
            if (!this.ws) {
                throw new Error('WebSocket is not connected');
            }
            this.ws?.send(data, type);
        },

        shell<T = any>(data: T): void {
            if (!this.ws) {
                throw new Error('WebSocket is not connected');
            }
            this.ws?.send(data, 'SHELL');
        }
    },
});